package com.bowlong.third.payment.p91;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import com.bowlong.lang.NumEx;
import com.bowlong.net.http.HttpParser;
import com.bowlong.util.MapEx;
import com.bowlong.util.Ref;

public class Payment91 {

	public static final String FAIL = "{\"ErrorCode\":\"0\",\"ErrorDesc\":\"接收失败\"}";
	public static final String SUCC = "{\"ErrorCode\":\"1\",\"ErrorDesc\":\"接收成功\"}";

	/*
	 * 接收由 91 平台服务器发送给各个应用服务商的支付购买结果 91 服务器通知 给应用服务器 参数 参数名 说明(没有说明可选的参数,为必传参数)
	 * AppId : 应用 ID Act : 1 ProductName : 应用名称 ConsumeStreamId : 消费流水号
	 * CooOrderSerial : 商户订单号 Uin : 91 账号 ID GoodsId : 商品 ID GoodsInfo : 商品名称
	 * GoodsCount : 商品数量 OriginalMoney : 原始总价(格式:0.00) OrderMoney :
	 * 实际总价(格式:0.00) Note : 即支付描述(客户端 API 参数中的 payDescription 字段) 购买时客户端应用通过 API
	 * 传入,原样返回给应用服务器 开发者可以利用该字段,定义自己的扩展数据。例如区分游戏 服务器 PayStatus : 支付状态:0=失败,1=成功
	 * CreateTime : 创建时间(yyyy-MM-dd HH:mm:ss) Sign : 以上参数的 MD5 值,其中 AppKey 为
	 * 91SNS 平台分配的应用 密钥 String.Format(
	 * "{0}{1}{2}{3}{4}{5}{6}{7}{8}{9:0.00}{10:0.00}{1 1}{12}{13:yyyy-MM-dd HH:mm:ss}{14}"
	 * , AppId,Act, ProductName,ConsumeStreamId, CooOrderSerial, Uin, GoodsId,
	 * GoodsInfo, GoodsCount, OriginalMoney, OrderMoney, Note, PayStatus,
	 * CreateTime, AppKey).HashToMD5Hex()
	 */
	// AppId=100010&Act=1&ProductName=%e6%98%9f%e9%99%85%e8%bf%b7%e8%88%aaDemo&
	// ConsumeStreamId=1-10001-20101214233421-1-6422&
	// CooOrderSerial=a258337465ff4e85b78b2c23d7046098&
	// Uin=155451276&Goo dsId=80370&GoodsInfo=X1000%e6%88%98%e6%96%97%e6%9c%ba&
	// GoodsCount=1&OriginalMoney=0.01&OrderMoney=0.01&Note=%e6%88%98%e6%96%97%e6%9c%ba&
	// PayStatus=1&CreateTime=2010-12-14
	// 23:34:21&Sign=2667575c8582b52a5fe5aa09141b076b
	public static boolean checkOrder(String body, Ref<Double> money,
			Ref<Integer> orderId, Ref<String> errMsg, Ref<String> retToChannel)
			throws IOException {
		if (body == null || body.isEmpty()) {
			money.val = 0.0;
			orderId.val = 0;
			retToChannel.val = FAIL;
			errMsg.val = "body == null || body.isEmpty()";
			return false;
		}
		// 处理充值回调
		String enc = body;
		int p1 = enc.indexOf("CooOrderSerial=");
		int p2 = enc.indexOf("&Sign=");
		if (p1 < 0 || p2 <= 0) {
			money.val = 0.0;
			orderId.val = 0;
			retToChannel.val = FAIL;
			errMsg.val = "body not found order_id and sign";
			return false;
		}

		String str = enc.substring(p1, p2);
		// String sign = enc.substring(p2 + 6, enc.length());

		Map<String, List<String>> map = HttpParser.parseQueryString(str,
				"UTF-8");
		if (map == null || map.isEmpty()) {
			money.val = 0.0;
			orderId.val = 0;
			retToChannel.val = FAIL;
			errMsg.val = "body parse error";
			return false;
		}
		// {"account":"888","amount":"0.01","order_id":"2012071076302411","billno":"2012071076302411","status":"1"}
		// String account = (String) MapEx.getList(map, "account").get(0);
		double amount = NumEx.stringToDouble((String) MapEx.getList(map,
				"OriginalMoney").get(0));
		// String order_id = (String) MapEx.getList(map, "order_id").get(0);
		int billno = NumEx.stringToInt((String) MapEx.getList(map,
				"CooOrderSerial").get(0));
		int status = NumEx.stringToInt((String) MapEx.getList(map, "PayStatus")
				.get(0));

		{ // 数据校验
			// Map encrypt = RSAEncrypt.decode(sign);
			// String eoid = MapEx.getString(encrypt, "order_id");
			// int ebillno = MapEx.getInt(encrypt, "billno");
			// if (!eoid.equals(order_id) || billno != ebillno) {
			// // 数据校验错误
			// res.setContent(ChannelBuffers.copiedBuffer("fail",
			// CharsetUtil.UTF_8));
			// setHeaders(res);
			// ChannelFuture future = me.getChannel().write(res);
			// future.addListener(ChannelFutureListener.CLOSE);
			// // dealyDlose(me.getChannel());
			// return;
			// }
		}

		if (status != 1) { // 支付状态:0=失败,1=成功
			money.val = amount;
			orderId.val = 0;
			retToChannel.val = SUCC;
			errMsg.val = "status:" + status + " is false";
			return false;
		}
		money.val = 0.0;
		orderId.val = billno;
		retToChannel.val = SUCC;
		errMsg.val = "status:" + status + " is ok";
		return true;
	}
}
